/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ru.ibrae.mchs.radiation.entities.controllers;

import ru.ibrae.mchs.radiation.entities.CrossZon;
import ru.ibrae.mchs.radiation.entities.CrossZonPK;
import ru.ibrae.mchs.radiation.entities.controllers.exceptions.NonexistentEntityException;
import ru.ibrae.mchs.radiation.entities.controllers.exceptions.PreexistingEntityException;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import ru.ibrae.mchs.radiation.entities.DicIst;
import ru.ibrae.mchs.radiation.entities.DicZon;
import ru.ibrae.mchs.radiation.entities.Geoobject;
import java.util.ArrayList;
import java.util.Date;

/**
 *
 * @author murr
 */
public class CrossZonJpaController {

    public CrossZonJpaController() {
        emf = Persistence.createEntityManagerFactory("DesktopApplication4PU");
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(CrossZon crossZon) throws PreexistingEntityException, Exception {
        if (crossZon.getCrossZonPK() == null) {
            crossZon.setCrossZonPK(new CrossZonPK());
        }
        crossZon.getCrossZonPK().setIdZon(crossZon.getDicZon().getIdZon());
        crossZon.getCrossZonPK().setIdNp(crossZon.getGeoobject().getIdNp());
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            DicIst dicIst = crossZon.getDicIst();
            if (dicIst != null) {
                dicIst = em.getReference(dicIst.getClass(), dicIst.getIdIst());
                crossZon.setDicIst(dicIst);
            }
            DicZon dicZon = crossZon.getDicZon();
            if (dicZon != null) {
                dicZon = em.getReference(dicZon.getClass(), dicZon.getIdZon());
                crossZon.setDicZon(dicZon);
            }
            Geoobject geoobject = crossZon.getGeoobject();
            if (geoobject != null) {
                geoobject = em.getReference(geoobject.getClass(), geoobject.getIdNp());
                crossZon.setGeoobject(geoobject);
            }
            em.persist(crossZon);
            if (dicIst != null) {
                dicIst.getCrossZonSet().add(crossZon);
                dicIst = em.merge(dicIst);
            }
            if (dicZon != null) {
                dicZon.getCrossZonSet().add(crossZon);
                dicZon = em.merge(dicZon);
            }
            if (geoobject != null) {
                geoobject.getCrossZonSet().add(crossZon);
                geoobject = em.merge(geoobject);
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findCrossZon(crossZon.getCrossZonPK()) != null) {
                throw new PreexistingEntityException("CrossZon " + crossZon + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(CrossZon crossZon) throws NonexistentEntityException, Exception {
        crossZon.getCrossZonPK().setIdZon(crossZon.getDicZon().getIdZon());
        crossZon.getCrossZonPK().setIdNp(crossZon.getGeoobject().getIdNp());
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            CrossZon persistentCrossZon = em.find(CrossZon.class, crossZon.getCrossZonPK());
            DicIst dicIstOld = persistentCrossZon.getDicIst();
            DicIst dicIstNew = crossZon.getDicIst();
            DicZon dicZonOld = persistentCrossZon.getDicZon();
            DicZon dicZonNew = crossZon.getDicZon();
            Geoobject geoobjectOld = persistentCrossZon.getGeoobject();
            Geoobject geoobjectNew = crossZon.getGeoobject();
            if (dicIstNew != null) {
                dicIstNew = em.getReference(dicIstNew.getClass(), dicIstNew.getIdIst());
                crossZon.setDicIst(dicIstNew);
            }
            if (dicZonNew != null) {
                dicZonNew = em.getReference(dicZonNew.getClass(), dicZonNew.getIdZon());
                crossZon.setDicZon(dicZonNew);
            }
            if (geoobjectNew != null) {
                geoobjectNew = em.getReference(geoobjectNew.getClass(), geoobjectNew.getIdNp());
                crossZon.setGeoobject(geoobjectNew);
            }
            crossZon = em.merge(crossZon);
            if (dicIstOld != null && !dicIstOld.equals(dicIstNew)) {
                dicIstOld.getCrossZonSet().remove(crossZon);
                dicIstOld = em.merge(dicIstOld);
            }
            if (dicIstNew != null && !dicIstNew.equals(dicIstOld)) {
                dicIstNew.getCrossZonSet().add(crossZon);
                dicIstNew = em.merge(dicIstNew);
            }
            if (dicZonOld != null && !dicZonOld.equals(dicZonNew)) {
                dicZonOld.getCrossZonSet().remove(crossZon);
                dicZonOld = em.merge(dicZonOld);
            }
            if (dicZonNew != null && !dicZonNew.equals(dicZonOld)) {
                dicZonNew.getCrossZonSet().add(crossZon);
                dicZonNew = em.merge(dicZonNew);
            }
            if (geoobjectOld != null && !geoobjectOld.equals(geoobjectNew)) {
                geoobjectOld.getCrossZonSet().remove(crossZon);
                geoobjectOld = em.merge(geoobjectOld);
            }
            if (geoobjectNew != null && !geoobjectNew.equals(geoobjectOld)) {
                geoobjectNew.getCrossZonSet().add(crossZon);
                geoobjectNew = em.merge(geoobjectNew);
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                CrossZonPK id = crossZon.getCrossZonPK();
                if (findCrossZon(id) == null) {
                    throw new NonexistentEntityException("The crossZon with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(CrossZonPK id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            CrossZon crossZon;
            try {
                crossZon = em.getReference(CrossZon.class, id);
                crossZon.getCrossZonPK();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The crossZon with id " + id + " no longer exists.", enfe);
            }
            DicIst dicIst = crossZon.getDicIst();
            if (dicIst != null) {
                dicIst.getCrossZonSet().remove(crossZon);
                dicIst = em.merge(dicIst);
            }
            DicZon dicZon = crossZon.getDicZon();
            if (dicZon != null) {
                dicZon.getCrossZonSet().remove(crossZon);
                dicZon = em.merge(dicZon);
            }
            Geoobject geoobject = crossZon.getGeoobject();
            if (geoobject != null) {
                geoobject.getCrossZonSet().remove(crossZon);
                geoobject = em.merge(geoobject);
            }
            em.remove(crossZon);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<CrossZon> findCrossZonEntities() {
        return findCrossZonEntities(true, -1, -1);
    }

    public List<CrossZon> findCrossZonEntities(int maxResults, int firstResult) {
        return findCrossZonEntities(false, maxResults, firstResult);
    }

    private List<CrossZon> findCrossZonEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(CrossZon.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public CrossZon findCrossZon(CrossZonPK id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(CrossZon.class, id);
        } finally {
            em.close();
        }
    }

    public int getCrossZonCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<CrossZon> rt = cq.from(CrossZon.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

    public List<CrossZon> findActiveCrossZonEntities() {
        EntityManager em = getEntityManager();
        DicZonJpaController dzjc = new DicZonJpaController();
        GeoobjectJpaController gjc = new GeoobjectJpaController();
        DicIstJpaController dijc = new DicIstJpaController();
        try {
            Query q = em.createNativeQuery("select * from cross_zon where DATE_ZONN IS NULL");
            ArrayList<CrossZon> crossZons = new ArrayList<CrossZon>();
            for (Object object : q.getResultList()) {
                Object[] objects = (Object[]) object;
                CrossZon crossZon = new CrossZon();
                crossZon.setCrossZonPK(new CrossZonPK((Integer) objects[0], (Integer) objects[1], (Date) objects[2]));
                crossZon.setDateZonn(null);
                crossZon.setDicZon(dzjc.findDicZon(crossZon.getCrossZonPK().getIdZon()));
                crossZon.setGeoobject(gjc.findGeoobject(crossZon.getCrossZonPK().getIdNp()));
                crossZon.setActualZon((Boolean) objects[4]);
                crossZon.setDicIst(dijc.findDicIst((Integer) objects[5]));
                crossZons.add(crossZon);
            }
            return crossZons;
        } finally {
            em.close();
        }
    }

    public List<Integer> findActiveGeoobjIdsWithZone1() {
        EntityManager em = getEntityManager();
        Query q = em.createNativeQuery("SELECT cross_zon.ID_NP FROM cross_zon WHERE ID_ZON=1 AND DATE_ZONN IS NULL GROUP BY ID_NP");
        return q.getResultList();
    }

    public ArrayList<Integer> getActualCitiesByZone(Integer zoneId) {
        EntityManager em = getEntityManager();
        Query q = em.createNativeQuery("SELECT ID_NP FROM cross_zon WHERE ID_ZON=?1 AND DATE_ZONN IS NULL GROUP BY ID_NP ORDER BY ID_NP");
        q.setParameter(1, zoneId);
        return q.getResultList().isEmpty() ? null : new ArrayList<Integer>(q.getResultList());
    }
}
